<?php declare(strict_types=1);

namespace App\Bac\Handler\RBAC;

use Hyperf\DbConnection\Db;
use App\Helper\RespHelper;
use App\Bac\Model\RBAC\Menu;
use App\Exception\BusinessException;
use Hyperf\Di\Annotation\Inject;

class MenuHandler
{

    #[Inject]
    protected Menu $model;

    public function getList(): array
    {
        $query = $this->model::select(['*']);
        $rows = $query->orderBy('order')->get()->toArray();
        $rows = handleTreeList($rows);
        $total = count($rows);
        foreach ($rows as &$v1) {
            if (!(isset($v1['children']) && $v1['children']) && !$v1['parent_id']) {
                $v1['children'] = [];
            }
        }
        return compact("rows", "total");
    }

    public function addMenu(array $data): bool
    {
        $data['created_at'] = date('Y-m-d H:i:s', time());
        if ($this->model->where('name', $data['name'])->exists())
            throw new BusinessException(RespHelper::CODE_FAIL, "菜单已经存在");

        if (is_array($data['parent_id'])) {
            $data['parent_id'] = $data['parent_id'][count($data['parent_id']) - 1];
        }
        return $this->model->insert($data);
    }

    public function editMenu(int $id, array $data): bool
    {
        $info = $this->model->find($id);
        if (!$info)
            throw new BusinessException(RespHelper::CODE_NOTFOUND, "菜单不存在");
        if (isset($data['name']) && !empty(trim($data['name']))) {
            $info->name = trim($data['name']);
        }
        if (isset($data['url']) && !empty(trim($data['url']))) {
            $info->url = trim($data['url']);
        }
        if (isset($data['icon']) && !empty(trim($data['icon']))) {
            $info->icon = trim($data['icon']);
        }
        if (isset($data['order'])) {
            $info->order = $data['order'];
        }
        if (isset($data['show'])) {
            $info->show = $data['show'];
        }
        if (isset($data['additional']) && !empty(trim($data['additional']))) {
            $info->additional = trim($data['additional']);
        }
        if (isset($data['description']) && !empty(trim($data['description']))) {
            $info->description = trim($data['description']);
        }
        if (empty($data['parent_id'])) {
            $info->parent_id = 0;
        }else{
            if (is_array($data['parent_id'])) {
                $info->parent_id = $data['parent_id'][count($data['parent_id']) - 1];
            } else {
                $info->parent_id = $data['parent_id'];
            }
        }
        if (isset($data['permission_id'])) {
            $info->permission_id = $data['permission_id'];
        }
        return $info->save();
    }

    /**
     * 删除权限
     * @param $ids
     * @return int
     */
    public function delMenu($ids): int
    {
        if (!is_array($ids)) {
            if ($this->model->where('parent_id', $ids)->exists()) {
                throw new BusinessException(RespHelper::CODE_ERROR, "请先删除子菜单");
            }
        }
        return $this->model->destroy($ids);
    }

    /**
     * 获取用户菜单
     * @param int $uid
     * @param bool $isSuper
     * @return array
     */
    public function getMenuByAdmin(int $uid, bool $isSuper): array
    {
        $rows = [];
        $filed = ['id', 'parent_id', 'name', 'url', 'additional', 'icon', 'show'];
        try {
            if ($isSuper) {
                //超管，所有菜单
                $rows = $this->model->select($filed)->orderBy('order')->get()->toArray();
            } else {
                $userPermissionIds = Db::table('rbac_role_admin')->distinct()
                    ->join('rbac_role_permission', 'rbac_role_admin.role_id', '=', 'rbac_role_permission.role_id')
                    ->where('rbac_role_admin.uid', $uid)
                    ->pluck('pms_id')->toArray();
                // 如果用户没有绑定权限就不往下查了
                if (!empty($userPermissionIds)) {
                    $rows = $this->model->whereIn('permission_id', $userPermissionIds)->orderBy('order')
                        ->get($filed)->toArray();
                    //获取父级
                    $parentIds = array_column($rows, 'parent_id');
                    $parentList = $this->model->whereIn('id', $parentIds)
                        ->orderBy('order')->get($filed)->toArray();
                    $rows = array_merge($rows, $parentList);
                    $t = array_map('serialize', $rows);
                    $t = array_unique($t);
                    $rows = array_map('unserialize', $t);
                }
            }
        } catch (\Throwable $e) {
            throw new BusinessException(RespHelper::CODE_FAIL, "获取菜单失败" . $e->getMessage());
        }

        $list = [];
        foreach ($rows as $v) {
            if (!$v['show']) continue;
            $temp = [
                'id' => $v['id'], 'parent_id' => $v['parent_id'],
                'name' => $v['name'],
                'component' => $v['parent_id'] ? $v['url'] : "#",
                'show' => $v['show'], 'path' => $v['url'] ?: '',
                'meta' => ['icon' => $v['icon'], 'title' => $v['name']],
            ];
            $list[] = $temp;
        }
        $tree = handleTreeList($list);
        foreach ($tree as $v) {
            if (isset($v['children']) && !$v['children']) {
                unset($v['children']);
            }
        }
        return $tree;
    }
}
